package br.webcrawler.activities.webcrawler.xml;

import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.log4j.Logger;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.openqa.selenium.Cookie;

import br.webcrawler.activities.webcrawler.utils.Data;

/**
 * 
 * @author Gerson Groth
 */
public class DownloadActivity {
	//TODO - adicionar logs
	private static Logger logger = Logger.getLogger(DownloadActivity.class);
	private static int timeout = 20000;
	private static Map<String, String> cookies;

	private static Xml xml = new Xml();

	public static void download(String html, long activity) {
		Document doc = Jsoup.parse(html);

		Element element = null;
		String file = "activity_" + activity + ".tcx", user = "", maxHR = "";
		try {
			element = doc.getElementById("username");
			user = getTextElement(element);
		} catch (Exception e) {
		}

		try {
			element = doc.getElementById("bpmSummary");
			Element tbody = element.child(0);
			List<Element> tr = tbody.children();

			String maxHr = tr.get(1).getAllElements().get(2).text().split(" ")[0];

			element = doc.getElementById("pomSummary");
			tbody = element.child(0);
			tr = tbody.children();

			String percentHR = tr.get(1).getAllElements().get(2).text()
					.split(" ")[0];

			element = doc.getElementById("detailsHeartRateBox");
			int maxHRInt = 0;
			try {
				maxHRInt = Integer.parseInt(maxHr) * 100
						/ Integer.parseInt(percentHR);
				maxHR = Integer.toString(maxHRInt);
			} catch (Exception e) {
				// castError.add("http://connect.garmin.com/proxy/activity-service-1.1/tcx/activity/"+i+"?full=true");
			}
		} catch (Exception e) {
			// System.err.println("erro: " + e.getMessage());
		}

		xml.nextActivity(file, maxHR, user);

		setHeader(element, xml, doc);
		setSummary(element, xml, doc);
		setDetails(element, xml, doc);
		setLaps(element, xml, doc);
		setWeather(element, xml, doc);
		setAdditionalInfo(element, xml, doc);

		xml.saveActivity(activity);
	}

	private static String getTextElement(Element element) {
		if (element != null)
			return element.text();

		return "";
	}

	private static void setHeader(Element element, Xml xml, Document doc) {
		String activityName = "";
		String timestamp = "";
		String username = "";
		String activityTypeValue = "";
		String eventTypeValue = "";
		String courseValue = "";

		try {
			element = doc.getElementById("activityName");
			activityName = getTextElement(element);
		} catch (Exception exc) {
		}
		try {
			element = doc.getElementById("timestamp");
			timestamp = getTextElement(element);

		} catch (Exception exc) {
		}
		try {
			element = doc.getElementById("username");
			username = getTextElement(element);
		} catch (Exception exc) {
		}

		try {
			element = doc.getElementById("activityTypeValue");
			activityTypeValue = getTextElement(element);
		} catch (Exception exc) {
		}

		try {
			element = doc.getElementById("eventTypeValue");
			eventTypeValue = getTextElement(element);
		} catch (Exception exc) {
		}

		try {
			element = doc.getElementById("courseValue");
			courseValue = getTextElement(element);
		} catch (Exception exc) {
		}

		xml.addHeader(activityName, timestamp, username, activityTypeValue,
				eventTypeValue, courseValue);
	}

	private static void setSummary(Element element, Xml xml, Document doc) {
		String name;
		String value;
		xml.createSummary();
		try {
			element = doc.getElementById("detailsOverallBox");
			Element table = element.child(1);
			Element tbody = table.child(0);
			List<Element> tr = tbody.children();

			for (Element e : tr) {
				try {
					name = e.children().get(0).text().split(":")[0].trim()
							.replaceAll(" ", "");
					value = e.children().get(1).text().trim();
					xml.addSummary(name, value);
				} catch (Exception exc) {
				}
			}
		} catch (Exception exc) {
		}
	}

	private static void setDetails(Element element, Xml xml, Document doc) {
		xml.createDetails();
		String name;
		String value;

		// TIMING
		try {
			Element table = doc.getElementById("timeSummary");
			Element tbody = table.child(0);
			List<Element> tr = tbody.children();

			for (Element e : tr) {
				try {
					name = e.children().get(0).text().split(":")[0].trim()
							.replaceAll(" ", "");
					value = e.children().get(1).text().trim();
					xml.addTiming(name, value);
				} catch (Exception exc) {
				}
			}
		} catch (Exception exc) {
		}

		try {
			Element table = doc.getElementById("speedSummary");
			Element tbody = table.child(0);
			List<Element> tr = tbody.children();

			for (Element e : tr) {
				try {
					name = e.children().get(0).text().split(":")[0].trim()
							.replaceAll(" ", "");
					value = e.children().get(1).text().trim();
					xml.addTiming(name, value);
				} catch (Exception exc) {
				}
			}
		} catch (Exception exc) {
		}

		try {
			Element table = doc.getElementById("paceSummary");
			Element tbody = table.child(0);
			List<Element> tr = tbody.children();

			for (Element e : tr) {
				try {
					name = e.children().get(0).text().split(":")[0].trim()
							.replaceAll(" ", "");
					value = e.children().get(1).text().trim();
					xml.addTiming(name, value);
				} catch (Exception exc) {
				}
			}
		} catch (Exception exc) {
		}

		// Elevation

		try {
			element = doc.getElementById("detailsElevationBox");
			Element table = element.child(3).getAllElements().get(1);
			Element tbody = table.child(0);
			List<Element> tr = tbody.children();

			for (Element e : tr) {
				try {
					name = e.children().get(0).text().split(":")[0].trim()
							.replaceAll(" ", "");
					value = e.children().get(1).text().trim();
					xml.addElevation(name, value);
				} catch (Exception exc) {
				}
			}
		} catch (Exception exc) {
		}

		// HEART HATE
		try {
			Element table = doc.getElementById("bpmSummary");
			Element tbody = table.child(0);
			List<Element> tr = tbody.children();

			for (Element e : tr) {
				try {
					name = e.children().get(0).text().split(":")[0].trim()
							.replaceAll(" ", "");
					value = e.children().get(1).text().trim();
					xml.addHeartHate(name + "bpm", value);
				} catch (Exception exc) {
				}
			}
		} catch (Exception exc) {
		}

		try {
			Element table = doc.getElementById("pomSummary");
			Element tbody = table.child(0);
			List<Element> tr = tbody.children();

			for (Element e : tr) {
				try {
					name = e.children().get(0).text().split(":")[0].trim()
							.replaceAll(" ", "");
					value = e.children().get(1).text().trim();
					xml.addHeartHate(name + "Percent", value);
				} catch (Exception exc) {
				}
			}
		} catch (Exception exc) {
		}

		try {
			Element table = doc.getElementById("hrZonesSummary");
			Element tbody = table.child(0);
			List<Element> tr = tbody.children();

			for (Element e : tr) {
				try {
					name = e.children().get(0).text().split(":")[0].trim()
							.replaceAll(" ", "");
					value = e.children().get(1).text().trim();
					xml.addHeartHate(name + "Zones", value);
				} catch (Exception exc) {
				}
			}
		} catch (Exception exc) {
		}

		// Cadence
		try {
			element = doc.getElementById("detailsCadenceBox");
			Element table = element.child(3).getAllElements().get(1);
			Element tbody = table.child(0);
			List<Element> tr = tbody.children();

			for (Element e : tr) {
				try {
					name = e.children().get(0).text().split(":")[0].trim()
							.replaceAll(" ", "");
					value = e.children().get(1).text().trim();
					xml.addCadence(name, value);
				} catch (Exception exc) {
				}
			}
		} catch (Exception exc) {
		}

	}

	private static void setWeather(Element element, Xml xml, Document doc) {
		String name;
		String value;
		xml.createWeather();
		try {
			element = doc.getElementById("detailsWeatherInfoBox");
			element = element.getElementsByClass("detailsBoxCollapseArea")
					.first();

			for (int i = 0; i < element.childNodeSize(); i++) {
				try {
					Element aux = element.child(i);
					name = aux.attr("class").replace("weather-", "")
							.replace("-", "").trim().split(" ")[0];
					if (i == 0) {
						value = aux.attr("title").trim();
					} else {
						value = aux.text().trim().replace("°", " degrees");
						value = aux.text().trim().replace("℃", " degrees C");
					}
					xml.addWeather(name, value);
				} catch (Exception exc) {
				}
			}

		} catch (Exception exc) {
		}

	}

	private static void setAdditionalInfo(Element element, Xml xml, Document doc) {
		String name;
		String value;
		xml.createAdditionalInfo();
		try {
			element = doc.getElementById("detailsAdditionalInfoBox");
			element = element.getElementsByClass("detailsBoxCollapseArea")
					.first();
			element = element.child(1);
			Element tbody = element.child(0);
			List<Element> tr = tbody.children();

			for (int i = 0; i < tr.size(); i += 2) {
				try {
					name = tr.get(i).child(0).childNode(0).toString()
							.split(":")[0].replace(" ", "");
					value = tr.get(i + 1).text().trim();
					xml.addAdditionalInfo(name, value);
				} catch (Exception exc) {
				}
			}

		} catch (Exception exc) {
		}

	}

	private static void setLaps(Element element, Xml xml, Document doc) {

		String name;
		String value;
		String nrLaps = null;

		// TIMING
		try {

			element = doc.getElementById("detailsLapsBox");
			Element title = element.getElementsByClass("detailsBoxTitle")
					.first();
			nrLaps = title.child(0).text().trim();
			xml.createLaps(nrLaps);

			element = doc.getElementById("splitsTableContainer");
			String id = element.child(0).attr("id");

			element = doc.getElementById(id + ":normalTable:tb");
			List<Element> tr = element.children();

			String split = null, time = null, distance = null, avgPace = null;
			for (Element e : tr) {
				try {
					split = e.child(0).text();
					time = e.child(1).text();
					distance = e.child(2).text();
					avgPace = e.child(3).text();
					xml.addLap(split, time, distance, avgPace);
				} catch (Exception exc) {
				}
			}
		} catch (Exception exc) {
		}

	}

	public static void downloadAll() {
		xml.imprimeXML();
		xml = new Xml();
	}

	public static void setCookies(Set<Cookie> c) {
		cookies = new HashMap<String, String>();
		for (Cookie cookie : c) {
			cookies.put(cookie.getName(), cookie.getValue());
		}
	}

	public static void downloadTcx(long activity) {
		Connection.Response r;
		try {
			r = Jsoup
					.connect(
							"http://connect.garmin.com/proxy/activity-service-1.1/tcx/activity/"
									+ activity + "?full=true").maxBodySize(0)
					.cookies(cookies).ignoreContentType(true).timeout(timeout)
					.execute();
			OutputStreamWriter out = new OutputStreamWriter(
					new FileOutputStream(new java.io.File(Data.getInstance()
							.getTcxFolder() + "activity_" + activity + ".tcx")));

			out.write(r.body());

			out.close();
		} catch (Exception ex) {
			logger.error("Error downloading tcx " + activity + " :", ex);
		}

	}

	public static void downloadGpx(long activity) {
		Connection.Response r;
		try {

			r = Jsoup
					.connect(
							"http://connect.garmin.com/proxy/activity-service-1.1/gpx/activity/"
									+ activity + "?full=true").maxBodySize(0)
					.cookies(cookies).ignoreContentType(true).timeout(timeout)
					.execute();
			OutputStreamWriter out = new OutputStreamWriter(
					new FileOutputStream(new java.io.File(Data.getInstance()
							.getGpxFolder() + "activity_" + activity + ".gpx")));
			out.write(r.body());
			out.close();
		} catch (Exception ex) {
			logger.error("Error downloading gpx " + activity + " :", ex);
		}

	}
}
